﻿using Common;
using Microsoft.Win32;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace AutoUpdateConfig
{
    public class UploadCtrlViewModel:ObservableObject
    {
        #region Variables

        private static AutoUpdateConfigModel _autoUpdateConfig = new AutoUpdateConfigModel();

        OpenFileDialog openFileDialog;
        MongoDBHelper mongo;
        string curHospital;
        string startExes = "";
        string killsExe = "";
        FileInfoModel runPath = new FileInfoModel();
        FileInfoModel startPath = new FileInfoModel();
        List<string> fileNames;
        AutoUpdateConfigModel selectedAuto = new AutoUpdateConfigModel();

        ObservableCollection<FileInfoModel> listFile = new ObservableCollection<FileInfoModel>();
        ObservableCollection<AutoUpdateConfigModel> listAuto = new ObservableCollection<AutoUpdateConfigModel>();

        #endregion

        #region Constructor

        public UploadCtrlViewModel()
        {
            openFileDialog = new OpenFileDialog();
            fileNames = new List<string>();
            IsEnable = false;
            BtnIsEnable = false;
        }

        #endregion

        #region Properties

        public AutoUpdateConfigModel AutoUpdateConfig
        {
            get
            {
                return _autoUpdateConfig;
            }

            set
            {
                _autoUpdateConfig = value;
                RaisePropertyChanged("AutoUpdateConfig");
            }
        }

        public string StartExes
        {
            get
            {
                return startExes;
            }

            set
            {
                startExes = value;
                RaisePropertyChanged("StartExes");
            }
        }

        public string KillsExe
        {
            get
            {
                return killsExe;
            }

            set
            {
                killsExe = value;
                RaisePropertyChanged("KillsExe");
            }
        }

        public FileInfoModel RunPath
        {
            get
            {
                return runPath;
            }

            set
            {
                runPath = value;
                RaisePropertyChanged("RunPath");
            }
        }

        public FileInfoModel StartPath
        {
            get
            {
                return startPath;
            }

            set
            {
                startPath = value;
                RaisePropertyChanged("StartPath");
            }
        }


        public string CurHospital
        {
            get
            {
                return curHospital;
            }

            set
            {
                curHospital = value;
                GetAutoUpdateInfo();
                RaisePropertyChanged("CurHospital");
            }
        }

        public ObservableCollection<FileInfoModel> ListFile
        {
            get
            {
                return listFile;
            }

            set
            {
                listFile = value;
            }
        }

        public ObservableCollection<AutoUpdateConfigModel> ListAuto
        {
            get
            {
                return listAuto;
            }

            set
            {
                listAuto = value;
            }
        }

        public AutoUpdateConfigModel SelectedAuto
        {
            get
            {
                return selectedAuto;
            }

            set
            {
                if (value == null) return;
                selectedAuto = value;
                AutoUpdateConfig = selectedAuto;
                ChangeAutoUpdateContent();
                RaisePropertyChanged("SelectedAuto");
            }
        }

        private string display = "";
        public string Display
        {
            get
            {
                return display;
            }
            set
            {
                display = value;
                RaisePropertyChanged("Display");
            }
        }

        public bool IsEnable
        {
            get
            {
                return isEnable;
            }

            set
            {
                isEnable = value;
                RaisePropertyChanged("IsEnable");
            }
        }

        public bool BtnIsEnable
        {
            get
            {
                return btnIsEnable;
            }

            set
            {
                btnIsEnable = value;
                RaisePropertyChanged("BtnIsEnable");
            }
        }

        private bool isEnable = true;

        private bool btnIsEnable = false;


        #endregion

        #region 依赖属性

        #endregion

        #region Event

        #endregion

        #region Private Methods

        private void GetAutoUpdateInfo()
        {
            Hospital hospital = HospitalConfig.Instance.DicHospitals[curHospital];
            if (IPHelper.PingIP(hospital.Ip))
            {
                mongo = new MongoDBHelper(hospital.Ip, hospital.Port, hospital.DbName);
                ListAuto = mongo.Find(FilterDefinition<AutoUpdateConfigModel>.Empty, "AutoUpdateConfig").OrderByDescending(O => O.ServerVersionId).ToList().ToObservableCollection();
                RaisePropertyChanged("ListAuto");
                if (ListAuto.Count != 0)
                {
                    SelectedAuto = ListAuto.FirstOrDefault();
                    ChangeAutoUpdateContent();
                    IsEnable = selectedAuto.IsNewAdd;
                }
                else
                {
                    AutoUpdateConfig = null;
                }
                BtnIsEnable = true;
            }
            else
            {
                MessageBox.Show("当前医院无法连接");
            }
        }

        private void ChangeAutoUpdateContent()
        {
            IsEnable = AutoUpdateConfig.IsNewAdd;
            RunPath.LocalPath1 = AutoUpdateConfig.RunExeLocalPath;
            StartPath.LocalPath1 = AutoUpdateConfig.StartExeLocalPath;
            RunPath.LocalPath = "";
            StartPath.LocalPath = "";
            KillsExe = "";
            StartExes = "";
            ListFile.Clear();
            foreach (var item in AutoUpdateConfig.KillProcess)
            {
                KillsExe += item + ";";
            }
            foreach (var item in AutoUpdateConfig.StartProcess)
            {
                StartExes += item + ";";
            }
            foreach (var item in AutoUpdateConfig.DownLoadFiles)
            {
                FileInfoModel model = new FileInfoModel();
                ListFile.Add(model);
                model.LocalPath1 = item.FilePath;
            }
        }

        private void UpLoadRun()
        {
            openFileDialog.DefaultExt = ".exe";
            openFileDialog.Filter = "exe file|run.exe";
            openFileDialog.CheckFileExists = true;
            openFileDialog.CheckPathExists = true;
            openFileDialog.Multiselect = false;
            if ((bool)openFileDialog.ShowDialog())
            {
                RunPath.LocalPath = openFileDialog.FileName;
                RunPath.LocalPath1 = AutoUpdateConfig.XuNiPath + openFileDialog.SafeFileName;
                _autoUpdateConfig.RunExeLocalPath = runPath.LocalPath1;
            }
        }

        private void UploadStartExe()
        {
            openFileDialog.DefaultExt = ".exe";
            openFileDialog.Filter = "exe file|*.exe";
            openFileDialog.CheckFileExists = true;
            openFileDialog.CheckPathExists = true;
            openFileDialog.Multiselect = false;
            if ((bool)openFileDialog.ShowDialog())
            {
                StartPath.LocalPath = openFileDialog.FileName;
                StartPath.LocalPath1 = _autoUpdateConfig.LocalRootPath + openFileDialog.SafeFileName;
                _autoUpdateConfig.StartExeLocalPath = StartPath.LocalPath1;
            }
        }

        private void UpLoadFiles()
        {
            OpenFileDialog o = new OpenFileDialog();
            o.Multiselect = true;
            if ((bool)o.ShowDialog())
            {
                ListFile.Clear();
                fileNames.Clear();
                fileNames.AddRange(o.SafeFileNames);
                for (int i = 0; i < o.FileNames.Length; i++)
                {
                    FileInfoModel model = new FileInfoModel();
                    ListFile.Add(model);
                    model.LocalPath = o.FileNames[i];
                    model.LocalPath1 = AutoUpdateConfig.LocalRootPath + o.SafeFileNames[i];
                }
            }
        }

        private void Save()
        {
            if (AutoUpdateConfig == null)
            {
                MessageBox.Show("请核对信息后再保存");
            }
            Task.Factory.StartNew(async delegate
            {
                try
                {
                    IsEnable = false;
                    if (!string.IsNullOrEmpty(runPath.LocalPath))
                    {
                        Display = runPath.LocalPath;
                        _autoUpdateConfig.RunExeLocalPath = runPath.LocalPath1;
                        _autoUpdateConfig.RunExeDownLoadPath = mongo.UploadFile(runPath.LocalPath);
                    }

                    if (!string.IsNullOrEmpty(startPath.LocalPath))
                    {
                        Display = startPath.LocalPath;
                        _autoUpdateConfig.StartExeLocalPath = StartPath.LocalPath1;
                        _autoUpdateConfig.StartExePath = mongo.UploadFile(startPath.LocalPath);
                    }

                    _autoUpdateConfig.DownLoadFiles.Clear();
                    List<MongoTypeFileModel> list = new List<MongoTypeFileModel>();
                    for (int i = 0; i < listFile.Count; i++)
                    {
                        FileInfoModel item = listFile[i];
                        if (string.IsNullOrEmpty(item.LocalPath)) break;
                        Display = item.LocalPath;
                        ObjectId id = mongo.UploadFile(item.LocalPath);
                        MongoTypeFileModel model = new MongoTypeFileModel()
                        {
                            Id = id,
                            FielName = fileNames[i],
                            FilePath = item.LocalPath1
                        };
                        list.Add(model);
                    }
                    if (list.Count != 0)
                    {
                        _autoUpdateConfig.DownLoadFiles = list;
                    }
                    foreach (var item in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
                    {
                        if (item.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                            AutoUpdateConfig.UploadIps += item + "; ";
                    }
                    AutoUpdateConfig.ServerVersionId = mongo.Count<AutoUpdateConfigModel>("AutoUpdateConfig") + 1;
                    AutoUpdateConfig.IsNewAdd = false;
                    AutoUpdateConfig.UpLoadTime = DateTime.Now;
                    if (AutoUpdateConfig.ID.Equals(ObjectId.Empty))
                    {
                        Display = "正在添加更新配置";
                        await mongo.InsertAsync(AutoUpdateConfig, "AutoUpdateConfig");
                    }
                    else
                    {
                        Display = "正在更新配置";
                        await mongo.UpdateAsync(AutoUpdateConfig, AutoUpdateConfig.ID, "AutoUpdateConfig");
                    }
                    Display = "保存成功";
                    IsEnable = AutoUpdateConfig.IsNewAdd;
                }
                catch (Exception ex)
                {
                    LogHelper.Error(this.GetType(), ex);
                }
            });
        }

        private void AddNewVersion()
        {
            AutoUpdateConfigModel auto = new AutoUpdateConfigModel();
            AutoUpdateConfigModel model = new AutoUpdateConfigModel();
            if (listAuto.Count >= 1)
            {
                model = listAuto.FirstOrDefault();
                auto.UpdateTimer = model.UpdateTimer;
                auto.LocalRootPath = model.LocalRootPath;
                auto.RealStartExePath = model.RealStartExePath;
                auto.XuNiPath = model.XuNiPath;
            }
            auto.IsNewAdd = true;
            if (ListAuto.Count == 0)
            {
                auto.ServerVersion = new Version("1.0.1");
            }
            else
            {
                auto.ServerVersion = ExtensionMethods.CreateVersionByPreVersion(listAuto.Max(O => O.ServerVersion), 50);
            }
            ListAuto.Insert(0, auto);
            SelectedAuto = auto;
            IsEnable = auto.IsNewAdd;
        }

        private void Rollback()
        {
            if (SelectedAuto.ServerVersionId == listAuto.Max(O => O.ServerVersionId))
            {
                MessageBox.Show("才更新了这个版本你回滚个球！", "温馨提示" , MessageBoxButton.OK);
                return;
            }
            if (ListAuto.Count == 1)
            {
                MessageBox.Show("只有一个版本你回滚个球！", "温柔提示", MessageBoxButton.OK);
                return;
            }
            MessageBoxResult result= MessageBox.Show("请谨慎操作，是否要回滚？", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
            if(result== MessageBoxResult.OK)
            {
                AutoUpdateConfig = selectedAuto.CloneObj();
                AutoUpdateConfig.RollBackVersion = selectedAuto.ServerVersion;
                AutoUpdateConfig.ServerVersion = ExtensionMethods.CreateVersionByPreVersion(listAuto.Max(O => O.ServerVersion), 50);
                AutoUpdateConfig.ServerVersionId = listAuto.Max(O => O.ServerVersionId) + 1;
                AutoUpdateConfig.IsNewAdd = true;
                AutoUpdateConfig._id = ObjectId.Empty;
                ListAuto.Insert(0, AutoUpdateConfig);
                SelectedAuto = AutoUpdateConfig;
                IsEnable = AutoUpdateConfig.IsNewAdd;
                Display = "正在添加更新配置";
                AutoUpdateConfig.UpLoadTime = DateTime.Now;
                mongo.Insert(AutoUpdateConfig, "AutoUpdateConfig");
                AutoUpdateConfig.IsNewAdd = false;
                Display = "保存成功";
                IsEnable = AutoUpdateConfig.IsNewAdd;
            }
        }

        #endregion

        #region Public/Protected Methods


        /// <summary>
        /// 执行方法； 1：上传run 2：上传通过run启动得exe 3：上传更新文件集合 4：保存 5：新增版本号
        /// </summary>
        /// <param name="commond"></param>
        public void Excute(string commond)
        {
            switch (commond)
            {
                case "1":
                    UpLoadRun();
                    break;
                case "2":
                    UploadStartExe();
                    break;
                case "3":
                    UpLoadFiles();
                    break;
                case "4":
                    Save();
                    break;
                case "5":
                    AddNewVersion();
                    break;
                case "6":
                    AddFile();
                    break;
                case "7":
                    Rollback();
                    break;
            }
        }

        private void AddFile()
        {
            OpenFileDialog o = new OpenFileDialog();
            o.Multiselect = true;
            if ((bool)o.ShowDialog())
            {
                fileNames.AddRange(o.SafeFileNames);
                for (int i = 0; i < o.FileNames.Length; i++)
                {
                    FileInfoModel model = new FileInfoModel();
                    ListFile.Insert(0, model);
                    model.LocalPath = o.FileNames[i];
                    model.LocalPath1 = AutoUpdateConfig.LocalRootPath + o.SafeFileNames[i];
                }
            }
        }

        #endregion

        #region EventHandlers

        #endregion
    }
}
